package zpp_nape.dynamics;
import zpp_nape.Config;
import zpp_nape.Const;
import zpp_nape.util.Flags;
import DummyNapeMain;
import zpp_nape.util.Math;
import zpp_nape.util.Names;
import zpp_nape.util.Pool;
import zpp_nape.util.Lists;
import zpp_nape.shape.Circle;
import zpp_nape.shape.Edge;
import zpp_nape.space.Space;
import zpp_nape.shape.Polygon;
import zpp_nape.shape.Shape;
import zpp_nape.phys.FeatureMix;
import zpp_nape.phys.FluidProperties;
import zpp_nape.phys.Material;
import zpp_nape.phys.Body;
import zpp_nape.geom.AABB;
import zpp_nape.geom.Distance;
import zpp_nape.geom.Mat23;
import zpp_nape.geom.Vec2;
import zpp_nape.geom.VecMath;
import zpp_nape.geom.Collide;
import zpp_nape.dynamics.Arbiter;
import zpp_nape.dynamics.Contact;
import zpp_nape.constraint.Constraint;
import zpp_nape.dynamics.SpaceArbiterList;
import zpp_nape.constraint.Matrices;
import zpp_nape.constraint.PivotJoint;
import zpp_nape.constraint.WeldJoint;
import nape.util.Flags;
import nape.util.Lists;
import nape.util.Debug;
import nape.space.Space;
import nape.shape.Circle;
import nape.shape.Polygon;
import nape.shape.Edge;
import nape.shape.Shape;
import nape.phys.FluidProperties;
import nape.phys.Material;
import nape.phys.Body;
import nape.geom.AABB;
import nape.geom.Geom;
import nape.geom.Mat23;
import nape.geom.Vec2;
import nape.dynamics.Contact;
import nape.dynamics.Arbiter;
import nape.dynamics.InteractionFilter;
#if swc@:keep#end class ZPP_InteractionFilter{
    static public var zpp_pool:ZPP_InteractionFilter;
    public var next:ZPP_InteractionFilter;
    public var outer:InteractionFilter;
    #if(flash9&&flib)@:ns("flibdel")#end public inline function wrapper(){
        if(outer==null){
            outer=new InteractionFilter();
            {
                var o=outer.zpp_inner;
                {
                    #if NAPE_ASSERT var res={
                        o!=null;
                    };
                    if(!res)throw "assert("+"o!=null"+") :: "+("Free(in T: "+"ZPP_InteractionFilter"+", in obj: "+"outer.zpp_inner"+")");
                    #end
                };
                o.free();
                o.next=ZPP_InteractionFilter.zpp_pool;
                ZPP_InteractionFilter.zpp_pool=o;
            };
            outer.zpp_inner=this;
        }
        return outer;
    }
    #if(flash9&&flib)@:ns("flibdel")#end public inline function free(){
        outer=null;
    }
    public var shapes:ZNPList_ZPP_Shape;
    public var wrap_shapes:ShapeList;
    public var shared:Bool;
    #if(flash9&&flib)@:ns("flibdel")#end public inline function feature_cons(){
        shapes=new ZNPList_ZPP_Shape();
        shared=false;
    }
    #if(flash9&&flib)@:ns("flibdel")#end public inline function addShape(shape:ZPP_Shape){
        shapes.add(shape);
    }
    #if(flash9&&flib)@:ns("flibdel")#end public inline function remShape(shape:ZPP_Shape){
        shapes.remove(shape);
    }
    public function new(){
        feature_cons();
        collisionGroup=sensorGroup=fluidGroup=1;
        collisionMask=sensorMask=fluidMask=-1;
    }
    #if(flash9&&flib)@:ns("flibdel")#end public inline function copy(){
        var ret={
            if(ZPP_InteractionFilter.zpp_pool==null)new ZPP_InteractionFilter();
            else{
                var ret=ZPP_InteractionFilter.zpp_pool;
                ZPP_InteractionFilter.zpp_pool=ret.next;
                ret;
            }
        };
        ret.collisionGroup=collisionGroup;
        ret.collisionMask=collisionMask;
        ret.sensorGroup=sensorGroup;
        ret.sensorMask=sensorMask;
        ret.fluidGroup=fluidGroup;
        ret.fluidMask=fluidMask;
        return ret;
    }
    public var collisionGroup:Int;
    public var collisionMask:Int;
    public var sensorGroup:Int;
    public var sensorMask:Int;
    public var fluidGroup:Int;
    public var fluidMask:Int;
    #if(flash9&&flib)@:ns("flibdel")#end public inline function shouldCollide(x:ZPP_InteractionFilter){
        return(collisionGroup&x.collisionMask)!=0&&(x.collisionGroup&collisionMask)!=0;
    }
    #if(flash9&&flib)@:ns("flibdel")#end public inline function shouldSense(x:ZPP_InteractionFilter){
        return(sensorGroup&x.sensorMask)!=0&&(x.sensorGroup&sensorMask)!=0;
    }
    #if(flash9&&flib)@:ns("flibdel")#end public inline function shouldFlow(x:ZPP_InteractionFilter){
        return(fluidGroup&x.fluidMask)!=0&&(x.fluidGroup&fluidMask)!=0;
    }
    #if(flash9&&flib)@:ns("flibdel")#end public inline function invalidate(){
        {
            var cx_ite=shapes.begin();
            while(cx_ite!=null){
                var s=cx_ite.elem();
                s.invalidate_filter();
                cx_ite=cx_ite.next;
            }
        };
    }
}
